package com.alibaba.datax.core.util.geo.coogis;

import com.alibaba.datax.core.util.geo.MapGeo;
import com.alibaba.datax.core.util.geo.amap.dto.*;
import com.alibaba.datax.core.util.geo.response.GeoInfoResponse;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.URLEncoder;
import java.util.List;
import java.util.Objects;

public class CooGISGeo implements MapGeo {
    private static final Logger LOG = LoggerFactory.getLogger(CooGISGeo.class);
    private String coogisLocation;

    public CooGISGeo(String coogisLocation) {
        this.coogisLocation = coogisLocation;
    }

    /**
     * 地理编码
     *
     * @param address 结构化地址信息
     * @param city    指定查询的城市
     * @return location 坐标点 经度，纬度
     */
    @Override
    public GeoInfoResponse geo(String address, String city) {
        // long startTs = System.currentTimeMillis();

        String resStr = get(coogisLocation + "/api/coodatax/address/geocode/geo/?address=" + URLEncoder.encode(address));

        // long diff = System.currentTimeMillis() - startTs;
        // LOG.info("==============================================  :" + diff);

        if (resStr == null || resStr.trim().length() == 0) return null;
        JSONObject resObj = JSONObject.parseObject(resStr);

        if (resObj.getInteger("retCode") != 0) {
            LOG.error(resObj.getString("msg"));
            return null;
        }

        JSONObject data = resObj.getJSONObject("data");

        if (data == null)
            return null;

        JSONArray list = data.getJSONArray("list");

        if (list == null || list.size() == 0)
            return null;

        JSONObject finalObj = list.getJSONObject(0);
        JSONObject geometry = finalObj.getJSONObject("geometry");

        if (geometry == null)
            return null;

        String type = geometry.getString("type");

        if (StringUtils.isBlank(type))
            return null;

        type = type.toUpperCase();

        JSONArray coordinates = geometry.getJSONArray("coordinates");
        double x = coordinates.getDouble(0);
        double y = coordinates.getDouble(1);

        String wkt = String.format("%s (%f %f)", type, x, y);
        GeoInfoResponse response = GeoInfoResponse.builder().build();
        response.setLocation(wkt);
        return response;

    }

    /**
     * 根据location定位街道信息
     *
     * @param address 坐标点 经度，纬度
     * @return
     */
    @Override
    public GeoInfoResponse regeo(String address) {
        // long startTs = System.currentTimeMillis();

        String resStr = get(coogisLocation + "/api/coodatax/address/geocode/geo/?address=" + address);

        // long diff = System.currentTimeMillis() - startTs;
        // LOG.info("==============================================  :" + diff);

        if (resStr == null || resStr.trim().length() == 0) return null;
        ReGeoRootDTO resultInfo = JSONObject.parseObject(resStr, ReGeoRootDTO.class);
        return getReGeoResponse(resultInfo);
    }

    private GeoInfoResponse getReGeoResponse(ReGeoRootDTO resultInfo) {
        GeoInfoResponse response = GeoInfoResponse.builder().build();
        if (!Objects.isNull(resultInfo) && !Objects.isNull(resultInfo.getRegeocode())) {
            Regeocode regeocode = resultInfo.getRegeocode();
            AddressComponent addressComponent = regeocode.getAddressComponent();
            response.setStatus("成功");
            response.setInfocode(resultInfo.getInfocode());
            response.setProvince(addressComponent.getProvince());
            response.setCity(addressComponent.getCity());
            response.setDistrict(addressComponent.getDistrict());
            response.setFormatted_address(regeocode.getFormatted_address());
            response.setCityCode(addressComponent.getCitycode());
            return response;
        }
        return null;
    }

    /**
     * 处理响应体，转换
     *
     * @param geoRootDTO 参数实体
     * @return com.lucfzy.rest.dto.response.GeoInfoResponse
     * @Author liu-miss/lucfz
     * @Description 处理响应体，转换
     * @Date 2021/7/25 8:43
     **/
    private GeoInfoResponse getGeoInfoResponse(GeoRootDTO geoRootDTO) {
        GeoInfoResponse response = GeoInfoResponse.builder().build();
        if (!Objects.isNull(geoRootDTO) && !CollectionUtils.isEmpty(geoRootDTO.getGeocodes())) {
            List<Geocodes> geocodes = geoRootDTO.getGeocodes();
            if (CollectionUtils.isEmpty(geocodes)) {
                response.setStatus("失败");
                return response;
            }
            Geocodes apiReturn = geocodes.get(0);

            response.setStatus("成功");
            response.setInfocode(geoRootDTO.getInfocode());
            response.setProvince(apiReturn.getProvince());
            response.setCity(apiReturn.getCity());
            response.setDistrict(apiReturn.getDistrict());
            if (!CollectionUtils.isEmpty(apiReturn.getNeighborhood().getName())) {
                response.setCommunity(apiReturn.getNeighborhood().getName().get(0));
            }
            response.setFormatted_address(apiReturn.getFormatted_address());
            response.setCityCode(apiReturn.getCitycode());
            String location = apiReturn.getLocation();
            response.setLocation(location);
            return response;
        }
        return null;
    }
}


